#include "ScenePrecompiled.hxx"
#include "InternalMeshContextImpl.hxx"
#include "InternalSceneStaticImpl.hxx"
#include "InternalSceneConv.hxx"
#include "InternalSceneImpl.hxx"

void Eifersucht::MeshContext::_Internal_impl::_Cpy_link()
{
	if ( !_Triangulate_mesh() ) 
	{
		PrintToDebugWindowOnly8( 
			"MeshContext_Internal_impl: Warning: "
			"Failed to triangulate mesh." 
			);
		return;
	}

#pragma region Resolve skin deformations

	_m_pRef->lDeformation.pFaces = (&_m_pRef->vnFaces);
	_m_pRef->lDeformation.pControlPoints = (&_m_pRef->vnControlPoints);
	_Auto_const nSkin = _To_uint _m_pAttr->GetDeformerCount( Fbx::Deformer::eSkin );
	for ( auto uSkin = 0u; uSkin < nSkin; uSkin++ )
	{
		auto skinModifierStatus = Fbx::Status();
		auto skinModifier = MeshContext::Skin();
		_Auto_const pSkin = FbxCast<Fbx::Skin>( _m_pAttr->GetDeformer(
			uSkin, Fbx::Deformer::eSkin, &skinModifierStatus
			));

		if ( skinModifierStatus.Error() )
		{
			PrintToDebugWindowOnly8( 
				"MeshContext_Internal_impl: Warning: "
				"Failed to resolve skin mesh deformer." 
				);
			PrintToDebugWindowOnly8( 
				skinModifierStatus.GetErrorString() 
				);

			if ( pSkin )
			{
				return;
			}
		}
		else
		{
			skinModifier.pDeformation = (&_m_pRef->lDeformation);
		}

		_Auto_const nBone = _To_uint pSkin->GetClusterCount();
		for ( auto uBone = 0u; uBone < nBone; uBone++ )
		{
			auto clusterPtr = pSkin->GetCluster(uBone);
			auto boneNodePtr = clusterPtr->GetLink();

			if ( clusterPtr )
			{
				auto boneExtractedData = MeshContext::Bone();
				_Auto_const boneIndices = clusterPtr->GetControlPointIndices();
				_Auto_const boneWeights = clusterPtr->GetControlPointWeights();

				boneExtractedData.u1Id = uBone;
				_Auto_const numEntries = _To_uint clusterPtr->GetControlPointIndicesCount();
				for ( auto entryIndex = 0u; entryIndex < numEntries; entryIndex++ )
				{
					_Auto_const boneIndex = _To_uint boneIndices[entryIndex];
					_Auto_const boneWeight = _To_float boneWeights[entryIndex];

					boneExtractedData.vnf1Weight.push_back(boneWeight);
					boneExtractedData.vnu1ControlPoints.push_back(boneIndex);
					boneExtractedData.pChildTranformation = _m_pRef->m_pRef;
				}

				if ( numEntries )
				{
					auto tempTransformation = Reign::Vector3();
					auto bonePtr = &boneExtractedData;

					_Cast_vector3(tempTransformation, boneNodePtr->TranslationMax.Get()); bonePtr->LclTranslationMax = tempTransformation;
					_Cast_vector3(tempTransformation, boneNodePtr->TranslationMin.Get()); bonePtr->LclTranslationMin = tempTransformation;
					_Cast_vector3(tempTransformation, boneNodePtr->LclTranslation.Get()); bonePtr->LclTranslation = tempTransformation;

					_Cast_vector3(tempTransformation, boneNodePtr->ScalingMax.Get()); bonePtr->LclScaleMax = tempTransformation;
					_Cast_vector3(tempTransformation, boneNodePtr->ScalingMin.Get()); bonePtr->LclScaleMin = tempTransformation;
					_Cast_vector3(tempTransformation, boneNodePtr->LclScaling.Get()); bonePtr->LclScale = tempTransformation;

					bonePtr->LclRotationOrder = (TransformationData::RotationOrder)(boneNodePtr->RotationOrder.Get());
					_Cast_vector3(tempTransformation, boneNodePtr->RotationOffset.Get()); bonePtr->LclRotationOffset = tempTransformation;
					_Cast_vector3(tempTransformation, boneNodePtr->RotationPivot.Get()); bonePtr->LclRotationPivot = tempTransformation;
					_Cast_vector3(tempTransformation, boneNodePtr->PostRotation.Get()); bonePtr->LclPostRotation = tempTransformation;
					_Cast_vector3(tempTransformation, boneNodePtr->PreRotation.Get()); bonePtr->LclPreRotation = tempTransformation;
					_Cast_vector3(tempTransformation, boneNodePtr->RotationMax.Get()); bonePtr->LclRotationMax = tempTransformation;
					_Cast_vector3(tempTransformation, boneNodePtr->RotationMin.Get()); bonePtr->LclRotationMin = tempTransformation;
					_Cast_vector3(tempTransformation, boneNodePtr->LclRotation.Get()); bonePtr->LclRotation = tempTransformation;

					_Cast_vector3(tempTransformation, boneNodePtr->GeometricTranslation.Get()); bonePtr->GeometricRotation = tempTransformation;
					_Cast_vector3(tempTransformation, boneNodePtr->GeometricRotation.Get()); bonePtr->GeometricRotation = tempTransformation;
					_Cast_vector3(tempTransformation, boneNodePtr->GeometricScaling.Get()); bonePtr->GeometricScale = tempTransformation;


				}

				skinModifier.vnBones.push_back(boneExtractedData);
			}
		}

		_m_pRef->lDeformation.vnSkin.push_back(skinModifier);
	}

#pragma endregion Skin

	// ....

}